<?php
/**
 * Controller_Ajax_Autosugest
 *
 * Класс Controller_Ajax_Autosugest отвечает за обработку запросов связанных с общими действиями для разных сущностей
 *
 * @author Егоров Александр <slamer86@gmail.com>
 * @version 2.0
 */
class Controller_Ajax_Autosuggest extends Controller_Ajax {

	/**
	 * (non-PHPdoc)
	 * @see Controller_Ajax::actionSwitch()
	 */
	public function actionSwitch() {
	  Service_Debug::setDebug();
		switch ($this->arrRequest[2]) {
			case 'all':
				$this->getAll();
				break;
			case 'city':
				$this->getCities();
				break;
			default: $this->setError(404);
 		}
	}
	

	/**
	 * Получение автосаджест для всех географических объектов
	 *
	 */
	public function getAll() {
	  Service_Debug::setDebug();
	  Pressure::setStart();
	  $limit = 8;
		//$querySource = isset($_GET['query']) ? Service_Escape::absolutelyEscapeString($_GET['query']) : '';
		$querySource = Service_Escape::requestDataString('query', 'GET');
		if (strpos($querySource, ',')) $query = substr($querySource, 0, strpos($querySource, ','));
		else $query = $querySource;
		if ($query == $querySource) $query .= '%';
		$lang = Service_Translate::getLangByString($query);
		//if (!$lang) return $this->makeStandardError(Service_Translate::getText('Неизвестный язык'));
		if (!$lang) $lang = 'ru'; 		
		$userLang = Service_Translate::getLang();
		if (!$lang) return $this->makeStandardError(Service_Translate::getText('Неизвестный язык'));
		$queryLength = Service_Function::utf8_strlen($query);
		$arrSuggestions = array();
		$arrCounts = array();
		$arrIds = array();
		$time['init'] = Pressure::calculateCurrentDuration();
		
		Pressure::setStart();
		$objCity = new City();
		
		$arrCitites = $objCity->find('all', array(
			'select' => "CONCAT('city,', city.ID_city) AS 'city', city.ID_city, CONCAT(city.city_final_name_ru, ', ', country.country_final_name_ru) AS 'name_ru', CONCAT(city.city_final_name_en, ', ', country.country_final_name_en) AS name_en, COUNT(hotel.ID_hotel) AS count",
			'conditions' => "(city.city_final_name_ru LIKE '" . $query . "' OR city.city_final_name_en LIKE '" . $query . "')",
			'joins' => "LEFT JOIN country ON country.country_code = city.country_code 
									LEFT JOIN hotel USING(ID_city)",
			'group' => 'city.ID_city',
			'order' => "count DESC",
			'limit' => $limit));
		$arrCitiesIds = Service_ArrayConverter::getColumnAsString($arrCitites, 'ID_city');
		$arrSuggestions = Service_ArrayConverter::getColumn($arrCitites, 'name_' . $lang);
		$arrCounts = Service_ArrayConverter::getColumn($arrCitites, 'count');
		$arrIds = Service_ArrayConverter::getColumn($arrCitites, 'city');
		
		$size = sizeof($arrIds);
		$time['city'] = Pressure::calculateCurrentDuration();		
		if ($queryLength >= 3 && $size < $limit) { // Если запрос длинный то ищем еще и...
			// Еще и регионы :( 			
			Pressure::setStart();
			$objRegion = new Region();
			$arrRegions = $objRegion->find('all', array(
			'select' => "CONCAT('region,', ID_region) AS 'ID_region', region_final_name_" . $lang . ", region_type, country.country_final_name_" . $lang . ", COUNT(hotel.ID_hotel) AS count",
			'conditions' => "region_final_name_" . $lang . " LIKE '" . $query . "'",
			'joins' => "LEFT JOIN country USING(country_code)
									LEFT JOIN hotel USING(ID_region)",
			'group' => 'region.ID_region',
			'order' => "count DESC",
			'limit' => $limit - $size
			));
			$arrRegionNames = array();
			foreach ($arrRegions as $arrRegion) {
				$arrRegionNames[] = View_Region::getName($arrRegion, 1, null, true) . ', ' . View_Country::getName($arrRegion);
			}
			$arrSuggestions = array_merge($arrSuggestions, $arrRegionNames);
			$arrCounts = array_merge($arrCounts, Service_ArrayConverter::getColumn($arrRegions, 'count'));
			$arrIds = array_merge($arrIds, Service_ArrayConverter::getColumn($arrRegions, 'ID_region'));
			$size += sizeof($arrRegions);
			$time['region'] = Pressure::calculateCurrentDuration();
			// Отели			
			Pressure::setStart();
			if ($size < $limit) {
				$objHotel = new Hotel();
				$arrHotels = $objHotel->find('all', array(
				'select' => "CONCAT('hotel,', hotel.ID_hotel, ',', hotel.country_url, '/',hotel.city_url, '/',hotel.hotel_url) AS 'url', 
										 CONCAT(hotel.hotel_final_name_" . $lang . ", ', ', city.city_final_name_" . $lang . ", ', ', country.country_final_name_" . $lang . ") AS 'name'",
				'conditions' => "hotel.hotel_final_name_" . $lang . " LIKE '" . $query . "'",
				'joins' => "INNER JOIN city ON city.ID_city = hotel.ID_city
									  INNER JOIN country ON country.country_code = city.country_code",
				'order' => "city.nr_hotels DESC",
				'limit' => $limit - $size));
				$arrSuggestions = array_merge($arrSuggestions, Service_ArrayConverter::getColumn($arrHotels, 'name'));
				$arrIds = array_merge($arrIds, Service_ArrayConverter::getColumn($arrHotels, 'url'));
				if (sizeof($arrHotels)) $arrCounts = array_merge($arrCounts, array_fill(0, sizeof($arrHotels), 1)); 
				$size += sizeof($arrHotels);
			}
			$time['hotels'] = Pressure::calculateCurrentDuration();
			// Страны
			Pressure::setStart();
			if ($size < $limit) {
				$objCountry = new Country();
				$arrCounties = $objCountry->find('all', array(
					'select' => "CONCAT('country,', country_code) AS 'ID_country', country_final_name_" . $lang . ", country.country_final_name_" . $lang . ", COUNT(hotel.ID_hotel) AS count",
					'conditions' => "country_final_name_" . $lang . " LIKE '" . $query . "' AND nr_hotels < 600",
					'joins' => "LEFT JOIN hotel USING(country_code)",
					'group' => 'country.country_code',
					'order' => "count DESC",
					'limit' => $limit - $size));
				$arrSuggestions = array_merge($arrSuggestions, Service_ArrayConverter::getColumn($arrCounties, 'country_final_name_' . $lang));
				$arrCounts = array_merge($arrCounts, Service_ArrayConverter::getColumn($arrCounties, 'count'));
				$arrIds = array_merge($arrIds, Service_ArrayConverter::getColumn($arrCounties, 'ID_country'));
				$size += sizeof($arrCounties);
			}
			$time['country'] = Pressure::calculateCurrentDuration();
		}
		
		// Ищем города дополнительные
		if ($size < $limit) {
			Pressure::setStart();
			$arrAdditionalCitites = $objCity->find('all', array(
				'select' => "CONCAT('city,', city.ID_city) AS 'city', CONCAT(city.city_final_name_ru, ', ', country.country_final_name_ru) AS 'name_ru', CONCAT(city.city_final_name_en, ', ', country.country_final_name_en) AS name_en, COUNT(hotel.ID_hotel) AS count",
				'conditions' => "(city.city_final_name_ru LIKE '%" . $query . "%' OR city.city_final_name_en LIKE '%" . $query . "%')" . ($arrCitiesIds ? " AND ID_city NOT IN (" . $arrCitiesIds . ")" : ""),
				'joins' => "LEFT JOIN country ON country.country_code = city.country_code
										LEFT JOIN hotel USING(ID_city)",
				'group' => 'city.ID_city',
				'order' => "count DESC",
				'limit' => $limit - $size));
			//$arrCitites = array_merge($arrCitites, $arrAdditionalCitites);
			$arrSuggestions = array_merge($arrSuggestions, Service_ArrayConverter::getColumn($arrAdditionalCitites, 'name_' . $lang));
			$arrIds = array_merge($arrIds, Service_ArrayConverter::getColumn($arrAdditionalCitites, 'city'));
			$arrCounts = array_merge($arrCounts, Service_ArrayConverter::getColumn($arrAdditionalCitites, 'count'));
			$size += sizeof($arrAdditionalCitites);
			$time['add_city'] = Pressure::calculateCurrentDuration(); 			
		}
		if (!sizeof($arrSuggestions) && $lang == 'en' && Service_Translate::getLang() == 'ru') {
			Pressure::setStart();
			$antiQuery = Service_Function::changeLayot($querySource, 'ru');
			$arrCitites = $objCity->find('all', array(
				'select' => "CONCAT('city,', city.ID_city) AS 'city', city.ID_city, CONCAT(city.city_final_name_ru, ', ', country.country_final_name_ru) AS 'name_ru', CONCAT(city.city_final_name_en, ', ', country.country_final_name_en) AS name_en, city.nr_hotels",
				'conditions' => "(city.city_final_name_ru LIKE '" . $antiQuery . "%')",
				'joins' => "LEFT JOIN country ON country.country_code = city.country_code
										LEFT JOIN hotel ON country.country_code = hotel.country_code",
				'group' => 'city.ID_city',
				'order' => "city.nr_hotels DESC",
				'limit' => $limit));
			if (sizeof($arrCitites)) $lang = 'ru';
			$arrSuggestions = Service_ArrayConverter::getColumn($arrCitites, 'name_' . $lang);
			$arrCounts = Service_ArrayConverter::getColumn($arrCitites, 'nr_hotels');
			$arrIds = Service_ArrayConverter::getColumn($arrCitites, 'city');
			$time['latin'] = Pressure::calculateCurrentDuration();
		}		
		
		if (empty($arrSuggestions) && $queryLength >= 3) {
			$objDebug = new Debug();
	  	$objDebug->setFields(array('debug_name' => 'Autossugest not found', 'debug_text' => $query));
	  	$objDebug->save();
		}
		
		$this->arrReturn = array(
			'suggestions' => $arrSuggestions,
			'counts' => $arrCounts,
 			'data' => $arrIds, 
			'query' => $querySource,
			'time' => $time,
			'antiQuery' => (isset($antiQuery) ? $antiQuery : '')
		);	
	}

	/**
	 * Получение автосаджест для городов
	 *
	 */
	public function getCities() {
	  Service_Debug::setDebug();
		$querySource = Service_Escape::requestDataString('query', 'GET');
		$query = substr($querySource, 0, strpos($querySource, ','));
		if ($query == $querySource) $query .= '%';
		$lang = Service_Translate::getLangByString($query);
		$userLang = Service_Translate::getLang();
		//if (!$lang) return $this->makeStandardError(Service_Translate::getText('Неизвестный язык'));
		if (!$lang) $lang = 'ru'; 
		$queryLength = Service_Function::utf8_strlen($query);
		
		$objCity = new City();
		$arrCitites = $objCity->find('all', array(
			'select' => "city.ID_city, CONCAT(city.city_final_name_ru, ', ', country.country_final_name_ru) AS 'name_ru', CONCAT(city.city_final_name_en, ', ', country.country_final_name_en) AS name_en",
			'conditions' => "(city.city_final_name_ru LIKE '" . $query . "' OR city.city_final_name_en LIKE '" . $query . "')",
			'joins' => "LEFT JOIN country ON country.country_code = city.country_code"));
		$arrCitiesIds = Service_ArrayConverter::getColumnAsString($arrCitites, 'ID_city');
		$arrSuggestions = Service_ArrayConverter::getColumn($arrCitites, 'name_' . $lang);
		$arrIds = Service_ArrayConverter::getColumn($arrCitites, 'ID_city');
		
		// Ищем города дополнительные
		if (sizeof($arrCitiesIds) < 10) {
			$arrAdditionalCitites = $objCity->find('all', array(
				'select' => "city.ID_city, CONCAT(city.city_final_name_ru, ', ', country.country_final_name_ru) AS 'name_ru', CONCAT(city.city_final_name_en, ', ', country.country_final_name_en) AS name_en",
				'conditions' => "(city.city_final_name_ru LIKE '%" . $query . "%' OR city.city_final_name_en LIKE '%" . $query . "%')" . ($arrCitiesIds ? " AND ID_city NOT IN (" . $arrCitiesIds . ")" : ""),
				'joins' => "LEFT JOIN country ON country.country_code = city.country_code"));
			//$arrCitites = array_merge($arrCitites, $arrAdditionalCitites);
			$arrSuggestions = array_merge($arrSuggestions, Service_ArrayConverter::getColumn($arrAdditionalCitites, 'name_' . $lang));
			$arrIds = array_merge($arrIds, Service_ArrayConverter::getColumn($arrAdditionalCitites, 'ID_city'));			
		}
		if (!sizeof($arrSuggestions) && $lang == 'en' && Service_Translate::getLang() == 'ru') {
			$antiQuery = Service_Function::changeLayot($query, 'ru');
			$arrCitites = $objCity->find('all', array(
				'select' => "CONCAT('city,', city.ID_city) AS 'city', CONCAT(city.city_final_name_ru, ', ', country.country_final_name_ru) AS 'name_ru', CONCAT(city.city_final_name_en, ', ', country.country_final_name_en) AS name_en",
				'conditions' => "(city.city_final_name_ru LIKE '" . $antiQuery . "%')",
				'joins' => "LEFT JOIN country ON country.country_code = city.country_code"));
			if (sizeof($arrCitites)) $lang = 'ru';			
		}		
		
		$this->arrReturn = array(
			'suggestions' => $arrSuggestions,
 			'data' => $arrIds, 
			'query' => $query,
			'antiQuery' => (isset($antiQuery) ? $antiQuery : '')
		);	
	}
}
?>